use crate::{csrr, exception::Exception, interrupt::Interrupt};

pub fn read() -> usize {
    csrr!(mcause)
}
pub fn cache() -> Cause {
    (read() as isize).into()
}
pub enum Cause {
    Interrupt(Interrupt),
    Exception(Exception),
}
impl From<isize> for Cause {
    fn from(value: isize) -> Self {
        if value >= 0 {
            Cause::Exception(Exception::try_from(value as usize).expect("Bug, Internal error"))
        } else {
            Cause::Interrupt(
                Interrupt::try_from(value.abs() as usize).expect("Bug, Internal error"),
            )
        }
    }
}
impl Into<isize> for Cause {
    fn into(self) -> isize {
        match self {
            Cause::Interrupt(x) => {
                let code: usize = x.into();
                -(code as isize)
            }
            Cause::Exception(x) => {
                let code: usize = x.into();
                code as isize
            }
        }
    }
}
